package threadlocal_test;

/**
 * @author Ajie
 * @date 2019-10-11
 * @function
 *
 * 可以看出，在每一个线程的确是没有互相影响，
 * 但是，我们知道，Integer是一个final修饰的类，在每次操作后，都会创建一个新的Integer，
 * 每次线程都是会在初始值的基础上创建，也就是每一次的地址都是不一样，然后进行操作。
 *
 */
public class ThreadLocal02 {
    public static void main(String[] args) {
        TestNum.main(null);
    }
}



class TestNum {
    // ①通过匿名内部类覆盖ThreadLocal的initialValue()方法，指定初始值
    private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() {
        public Integer initialValue() {
            return 0;
        }
    };

    // ②获取下一个序列值
    public int getNextNum() {
        System.out.println(Thread.currentThread().getName()+"  get:"+ seqNum.get()+"  set+1");


        seqNum.set(seqNum.get() + 1);
        //System.out.println();
        return seqNum.get();
    }


    public  ThreadLocal<Integer> getThreadLocal() {
        return seqNum;
    }

    public static void main(String[] args) {
        System.out.println("main thread start : "+seqNum.get());
        TestNum sn = new TestNum();
        // ③ 3个线程共享sn，各自产生序列号
        TestClient t1 = new TestClient(sn);
        TestClient t2 = new TestClient(sn);
        TestClient t3 = new TestClient(sn);
        t1.start();
        t2.start();
        t3.start();

        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("main thread result : "+seqNum.get());

    }

    private static class TestClient extends Thread {
        private TestNum sn;

        public TestClient(TestNum sn) {
            this.sn = sn;
        }

        public void run() {
            for (int i = 0; i < 100; i++) {

                sn.getNextNum();
                // ④每个线程打出3个序列值
//                System.out.println("thread[" + Thread.currentThread().getName() + "] --> sn["
//                        + sn.getNextNum() + "]  hashcode: "+sn.getThreadLocal().get().hashCode());
            }
        }
    }
}
